package xyz.comfyz.web.commons.framework.exceptions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import xyz.comfyz.web.commons.framework.result.ExpectedExeption;
import xyz.comfyz.web.commons.framework.result.SimpleErrorMessage;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;

/**
 * @author :    comfy
 * @date :      2018-05-07 11:43:20
 * @since :     1.8
 * <p>
 * 全局异常处理
 */
@RestControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {

    @SuppressWarnings("all")
    protected static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
    private static Logger log = LoggerFactory.getLogger(RestExceptionHandler.class);

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
        log.error(ex.getMessage(), ex);
        SimpleErrorMessage error = new SimpleErrorMessage(INTERNAL_SERVER_ERROR.value(), ex.getMessage());
        return new ResponseEntity<>(error, INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<Object> defaultHandlerException(Exception e) {
        log.error(e.getMessage(), e);
        SimpleErrorMessage error = new SimpleErrorMessage(INTERNAL_SERVER_ERROR.value(), e.getMessage());
        return new ResponseEntity<>(error, INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler(ExpectedExeption.class)
    public ResponseEntity<Object> handlerResponseException(ExpectedExeption e) {
        log.debug(e.getMessage(), e);
        if (e instanceof ExpectedExceptionHandler && ((ExpectedExceptionHandler) e).getHandler() != null)
            EXECUTOR.execute(((ExpectedExceptionHandler) e).getHandler());
        return new ResponseEntity<>(e.getErrorMessage(), BAD_REQUEST);
    }

}
